要將自己開發的應用程式容器化,想必需要製作自己的 Image。製作 Image 也是一種藝術,我們要如何讓自己的應用程式製造的 Image 能有更小的資源來使用。
我們都知道 Dockerfile 是建構 image 的檔案。
下面這張圖是 Dockerfile 可以使用的關鍵字
我覺得 cmd
和 ENTRYPOINT
這兩個可以理解一下,我有時會搞混哈。在 Dockerfile 中,只能有一個 ENTRYPOINT 或 CMD 指令,如果有多個ENTRYPOINT 或 CMD 指令則以最後一個為準。
下面是建立一個 Nginx Image 的 Dockerfile 範例
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y nginx
COPY . /var/www/html/
EXPOSE 80
#ENTRYPOINT ["nginx"]
CMD ["nginx", "-g", "daemon off;"]
有了 Dockerfile 後我們就可以建構 Image 了,使用 docker build -t {ImageName}:{tag01} .
建構
使用 docker images
查看建構的 image
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v0 55077273116a 20 minutes ago 222MB
Image 原則上應該越小越好,下面範例則是會把一些類似快取的東西或是歷史紀錄給拔掉
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y nginx \
&& rm -rf /var/lib/apt/lists/*
COPY . /var/www/html/
EXPOSE 80
#ENTRYPOINT ["nginx"]
CMD ["nginx", "-g", "daemon off;"]
最後 Image 減少了一些大小。
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v0.1 d17658937ea9 2 minutes ago 209MB
接下來直接給一個建構 Spring boot 的範例,專案如果是用 gradle 建立,應當會使用 gradle 進行建構和測試,所以我們使用了 gradle 進行第一層的建構和測試,當這一個 gradle 建構和測試結果成功後會有一個應用程式的 jar 檔。
這邊我們用運了 multi-stage 方式進行建構,這會使得 CICD 過程更加簡易。後續要運行 Jar 檔的 Image 透過指令(--from)取得前面鍵建構所產生的檔案 (artifacts)。
FROM gradle:4.10.2-slim as builder
USER root
COPY . .
RUN gradle clean build
FROM adoptopenjdk/openjdk8-openj9:jdk8u181-b13_openj9-0.9.0-slim
COPY --from=builder /home/gradle/build/libs/test-0.0.1-SNAPSHOT.jar /usr/local/test_workspace/test-0.0.1-SNAPSHOT.jar
RUN apt-get update && \
apt-get install -y tzdata ttf-dejavu fontconfig && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
mkdir /usr/local/logs
ENV LANG C.UTF-8
# Timezone
ENV TZ=Asia/Taipei
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "test-0.0.1-SNAPSHOT.jar"]
有關權限設置的內容可參考此鏈結